package com.study.skywalking.aspect;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.ThreadContext;
import org.apache.skywalking.apm.toolkit.trace.ActiveSpan;
import org.apache.skywalking.apm.toolkit.trace.TraceContext;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.UUID;

/**
 * Created by zhangbo on 2020/5/28.
 */
@Slf4j
@Aspect
@Component
public class LoggerAspect {

    @Value("${LOG.FLAG:true}")
    private boolean logFlag;

    @Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping) || " +
            "@annotation(org.springframework.web.bind.annotation.RequestMapping) || " +
            "@annotation(org.springframework.web.bind.annotation.PostMapping) || " +
            "@annotation(org.springframework.web.bind.annotation.DeleteMapping) || " +
            "@annotation(org.springframework.web.bind.annotation.PatchMapping) || " +
            "execution(* com.study.skywalking.api..*(..))")
    public void loggePointCut() {}

    @Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping) || " +
            "@annotation(org.springframework.web.bind.annotation.RequestMapping) || " +
            "@annotation(org.springframework.web.bind.annotation.PostMapping) || " +
            "@annotation(org.springframework.web.bind.annotation.DeleteMapping) || " +
            "@annotation(org.springframework.web.bind.annotation.PatchMapping)")
    public void traceIdPointCut() {};

    @Before("traceIdPointCut()")
    public void before(JoinPoint joinPoint) throws Throwable {
        log.debug("添加myTraceId");
        String myTraceId = UUID.randomUUID().toString().replaceAll("-","");
        ThreadContext.put("myTraceId", myTraceId);
    }

    @After("traceIdPointCut()")
    public void after(JoinPoint joinPoint) throws Throwable {
        log.debug("移除myTraceId");
        ThreadContext.remove("myTraceId");
    }

    @Around("loggePointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        if (logFlag) {
            if (null != joinPoint.getArgs() && joinPoint.getArgs().length > 0) {
                /*支持form提交*/
                log.info("接口请求参数:{}", joinPoint.getArgs());
//                ActiveSpan.info("接口请求参数:" + JSONObject.toJSONString(joinPoint.getArgs()));
            }
        }
        Object proceed = joinPoint.proceed();
        if (null != proceed) {
            try {
                log.info("接口返回参数:{}",proceed);
//                ActiveSpan.info("接口返回参数:" + JSONObject.toJSONString(proceed));
            } catch (Exception e) {
                log.info("接口返回参数:{}", proceed);
            }
        } else {
            log.info("接口返回参数:{}", "null");
        }
        return proceed;
    }

}
